package cn.ciis.ciis.equipment;

import cn.ciis.basic.base.BaseCache;
import cn.ciis.basic.base.BaseController;
import cn.ciis.basic.kit.ByteKit;
import cn.ciis.basic.kit.CiisKit;
import cn.ciis.basic.kit.EnumKit;
import cn.ciis.basic.kit.J2CacheKit;
import cn.ciis.basic.model.Enterprise;
import cn.ciis.basic.model.Equipment;
import cn.ciis.basic.model.mongo.DeviceConnectInfo;
import cn.ciis.basic.plugin.CiisPlugs;
import cn.ciis.basic.plugin.CiisSessionContext;
import cn.ciis.ciis.dictionary.DictionaryAdminService;
import cn.ciis.ciis.enterprise.EnterpriseAdminService;
import cn.ciis.server.CiisConstant;
import cn.ciis.server.CiisPacket;
import cn.ciis.sys.permission.Notes;
import cn.ciis.sys.permission.Remark;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import com.cybermkd.mongo.kit.MongoQuery;
import com.cybermkd.mongo.kit.page.MongoPage;
import com.cybermkd.mongo.kit.page.MongoPaginate;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 设备信息管理控制器
 * 描述：
 * @author 冉志林
 */
public class EquipmentAdminController extends BaseController {

    @Inject
    EquipmentAdminService srv;

    @Inject
    EnterpriseAdminService enterpriseAdminService;

    @Inject
    DictionaryAdminService dictionaryAdminService;//数据字典

	@Notes(value = "设备信息管理")
    @Remark(value = "设备信息列表")
    public void index() {
        Equipment mode = getModel(Equipment.class, "", true);
        Page<Equipment> paginate =  srv.paginate(getInt(PAGENUMBER, 1), getInt(PAGESIZE, 12), mode);

        for (Equipment equipment : paginate.getList()) {
            CiisKit.refreshByTio(equipment);//从Tio会话中更新设备数据
        }
        kModel(mode, paginate);
    }

    @Remark(value = "设备在线信息")
    public void connectInfo(){

	    int id = getInt("id",0);

	    if(id >0){
            Equipment equipment = (Equipment) srv.findById(id);

            MongoQuery mongoQuery = new MongoQuery();
            mongoQuery.use(EnumKit.MongoCollect.devices_connect_info.name()).eq("enterprise_code",equipment.getEnterprise().getCode())
            .eq("equipment_code",equipment.getCode()).descending("disconnectionAt");

            MongoPaginate page=new MongoPaginate(mongoQuery,getInt(PAGESIZE, 10),getInt(PAGENUMBER, 1));

            MongoPage page1 = page.find();

            Page<DeviceConnectInfo> result_page = new Page<>();

            result_page.setList(page1.getList());
            result_page.setPageNumber(getInt(PAGENUMBER, 1));
            result_page.setPageSize(page1.getCount());
            result_page.setTotalPage(page1.getTotalPage());
            result_page.setTotalRow(Convert.toInt(page1.getTotalRow()));
            kModel(equipment,result_page);
        }else{
            renderJson(Ret.fail("msg", "参数错误！"));
        }



    }

    @Remark(value = "设备信息添加或编辑页")
    public void addOrEdit(Integer id) {
        set("enterpriseList",enterpriseAdminService.findAll());
	    kAddOrEdit(srv.findById(id));
    }

    @Remark(value = "设备信息保存或修改")
    @Before(EquipmentAdminValidator.class)
    public void saveOrUpdate() {
        Equipment bean = getBean(Equipment.class);
        Ret ret = srv.saveOrUpdate(bean);
        if (ret.isOk()){
            J2CacheKit.set(BaseCache.EQUIPMENT_TIMED_CACHE,bean.getCode(),(Equipment)srv.findByFiled("code",bean.getCode()));
        }
        renderJson();
    }

    @Remark(value = "设备信息删除")
    public void deletes(String ids) {
        Ret ret = srv.logicalDeletion(ids,"state","1");
        String[] split = ids.split(",");
        for (String s : split) {
            Equipment equipment=(Equipment)srv.findById(s);
            J2CacheKit.set(BaseCache.EQUIPMENT_TIMED_CACHE,equipment.getCode(),new Equipment());
        }
        renderJson(ret);
    }

    @Remark(value = "配置传感器有效性")
    public void configure(String id){
        Equipment equipment = (Equipment) srv.findById(id);
        char[] ch = equipment.getValidity().toCharArray();

        Map<String,Object> map=new HashMap<String, Object>();
        map.put("pid",1);
        map.put("state",0);
        List<?> dictionaryList = dictionaryAdminService.findByFiled(map, "number", "asc");

        if(ch.length < dictionaryList.size()){
            int len =ch.length;
            ch = (char[]) ArrayUtil.resize(ch,dictionaryList.size());
            for (int i=len;i <dictionaryList.size();i++){
                ch[i]='0';
            }
        }
        set("dictionaryList",dictionaryList);
        set("equipment",equipment);
        set("validityList",ch);
    }

    @Remark(value = "有效值更改")
    public void changeValidity(int equimentId,int number,String state){
        Equipment equipment = (Equipment) srv.findById(equimentId);
        StringBuilder validity= new StringBuilder(equipment.getValidity());
        equipment.setValidity(validity.replace(number - 1, number, state.equals("1")?"0":"1").toString());
        Ret ret = srv.saveOrUpdate(equipment);
        if (ret.isOk()){
            Enterprise enterprise = equipment.getEnterprise();
            if (equipment.isConnect()){
                String bsId = CiisKit.getTioBsId(enterprise, equipment);
                ChannelContext context = Tio.getByBsId(CiisPlugs.ciisServerTioConfig, bsId);
                CiisSessionContext ciisSessionContext = (CiisSessionContext) context.get("ciisSessionContext");
                Optional<Equipment> sessionContextEquipment = ciisSessionContext.getEquipment();
                if (sessionContextEquipment.isPresent()) {
                    sessionContextEquipment.get().setValidity(equipment.getValidity());
                }
            }

        }
        kSuccess(ret);
    }

    @Remark(value = "设备设置灌溉计划")
    public void plan(int id){
        Equipment equipment=(Equipment) srv.findById(id);
//        if(equipment.isConnect()){
//            int length = equipment.getValidity().length();//设备数
//            CiisPacket ciisPacket=new CiisPacket();
//            ciisPacket.setType(ByteKit.hexStr2Bytes("CA"));
//            ciisPacket.setEnterprise(ByteKit.hexStr2Bytes(equipment.getEnterprise().getCode()));
//            ciisPacket.setDevice(ByteKit.hexStr2Bytes(equipment.getCode()));
//            ciisPacket.setCmd(ByteKit.hexStr2Bytes("5AA5"));
//            ciisPacket.setBody(ByteKit.hexStr2Bytes("000201"));
//            CiisKit.sendMsg(equipment, ciisPacket);
//        }else{
//            renderText("设备不在线！");
//        }
        //issued(CiisKit.getTioBsId(equipment.getEnterprise(),equipment),CiisConstant.AUTOMATIC_MODE);
        set("bsId",CiisKit.getTioBsId(equipment.getEnterprise(),equipment));
        set("equipment",equipment);
    }


    @Remark(value = "工作模式及启停命令消息发送")
    public void issued(String bsid,String msg){
	    if (StrKit.notBlank(bsid)){
            Ret ret = CiisKit.getTioBsId(bsid);
            CiisPacket ciisPacket=new CiisPacket();
            ciisPacket.setType(ByteKit.hexStr2Bytes("CA"));
            ciisPacket.setEnterprise(ByteKit.hexStr2Bytes(ret.getStr("enterpriseCode")));
            ciisPacket.setDevice(ByteKit.hexStr2Bytes(ret.getStr("equipmentCode")));
            ciisPacket.setCmd(ByteKit.hexStr2Bytes("5AA5"));
            ciisPacket.setBody(ByteKit.hexStr2Bytes(msg));
            J2CacheKit.set(BaseCache.WS_SESSION_ID_DICTIONARY,bsid+msg,getLoginAccount().getWebSocketSessionKey());
            String str="";
            switch (msg){
                case CiisConstant.AUTOMATIC_MODE:
                    str="自动工作模式";
                    break;
                case CiisConstant.MANUAL_MODE:
                    str="人工工作模式";
                    break;
                case CiisConstant.STOP_COMMAND:
                    str="停止";
                    break;
                case CiisConstant.PAUSE_COMMAND:
                    str="暂停";
                    break;
            }
            if (CiisKit.sendMsg(bsid, ciisPacket)){
                kSuccess(str+"命令下发成功");
            }else{
                kFail(str+"命令下发失败");
            }
        }
    }
}